<?php
/**
 * Контроллер отвечающий за вход зарегистрированных пользователей
 * 
 * LICENSE: Free to use license
 * 
 * @copyright 	2009
 * @author 		Яковлев Иван Yak1980@list.ru | Best4u.mail@gmail.com
 * @version		$id:$
 * @link 
 * @since 
 */

//require_once 'Zend/Controller/Action.php';

class LoginController extends System_Controller_DefaultAction
{
    private $_baseUrl = null;
    
    /**
     * Контейнер для хранения объекта Zend_Auth
     */
	private $_auth = null;

	/**
	 * Контейнер для хранения объекта формы
	 */
    private $_form = null;
	
	/**
	 * Контейнер для хранения идентификационных данных вошедшего пользователя 
	 */
	private $_identity = null;
	
	/**
	 * Контейнер для хранения сессионных данных
	 */
	private $_session = null;
	
	/**
	 * Контейнер для хранения запроса пользователя куда он хочет попасть после авторизации
	 */
	private $_requestUri = null;

	/**
	 * Инициализация необходимых параметров контроллер
	 */
	public function init()
	{
		// генерируем форму логина
        $this->_form = new Form_Login();
        
        // берем объект Zend_Auth
        $this->_auth = Zend_Auth::getInstance();
        
        // задаем сессию для хранения ошибки авторизации пользователя
        $this->_session = new Zend_Session_Namespace('authError');
        
        // Передаем в объект вида базовый путь в данном случае если адрес к нашему сайту
		// имеет вид http://localhost/kld-zft
		// то baseUrl = /kld-zft
		$this->_baseUrl = $this->_request->getBaseUrl();
		
		// Задаем заголовок для тега <head> страницы
		$this->view->headTitle('Вход');
		
		// подключаем необходимые css таблицы стилей в зависимости от модуля и контроллера
		$this->view->headLink()->appendStylesheet($this->view->themeUrl()
		    . '/css/' . $this->_request->getModuleName() . '-'
		    . $this->_request->getControllerName() . '-layout.css'
		    . $this->view->cacheVer, 'screen');
		    
		// Сохраняем адрес запрашиваемого пользователем ресурса если он есть 
		if ($requestUri = $this->getRequest()->getParam('_requestUri'))
		    $this->_requestUri = $requestUri;
		    $this->view->requestUri = $this->_requestUri;
		    
	}
	
    
	/**
     * The default action - show the home page
     */
    public function indexAction ()
    {
    // отправляем форму в объект вида
        $this->view->form = $this->_form;
        
		/**
		 * если отправлен post запрос обрабатываем его
		 * 
		 * @param string $_POST['login'] - логин
		 * @param string $_POST['password'] - пароль
		 */ 
	    if ($this->getRequest()->isPost()) {
	    	if ($this->_form->isValid($_POST)) { // если форма прошла проверку
	    		// получаем проверенные (безопасные) данные логина и пароля для дальнейшей обработки
	    		$login = $this->_form->getValue('login');
	    		$password = $this->_form->getValue('password');
	    		
	    		// выполняем процесс авторизации пользователя:
	    		// 1. Этап проверка без шифрования пароля
	    		$db = Zend_Registry::get('db');
	    		// создаем адаптер
        		$adapter = new Zend_Auth_Adapter_DbTable(
        		    $db,
        		    'users', // имя таблицы
        		    'user_login', // имя поля, по которому осуществляется идентивикация
        		    'user_pwd' // имя поля, по которому осуществляем проверку
        		);
        		$adapter->setIdentity($login)
        		        ->setCredential($password);
        		// проверяем наличе пользователя в базе данных
	       		$result = $this->_auth->authenticate($adapter);
	       		
	       		// 2. Этап проверки если первый этап не прошел проверку, то
	       		// запускаем второй этап (проверка с шифрованием пароля)
	       		if (!$result->isValid()) {
	       		    $adapter = new Zend_Auth_Adapter_DbTable(
            		    $db,
            		    'users', // имя таблицы
            		    'user_login', // имя поля, по которому осуществляется идентивикация
            		    'user_pwd', // имя поля, по которому осуществляем проверку
            		    'MD5(?)' // SQL-функция шифрования
            		);
            		$adapter->setIdentity($login)
            		        ->setCredential($password);
            		// проверяем наличе пользователя в базе данных
    	       		$result = $this->_auth->authenticate($adapter);
	       		}
        		
	    		// проверяем пройдена ли авторизация пользователя
        		if ($result->isValid()) {
        			/**
        			 * The next line stores the entire database row in the users
        			 * Zend_Auth identity. Normally only the 'identity' column—
        			 * in this case, the e-mail—is stored as a string. By
        			 * storing the entire record, you can access the user's
        			 * name and ID too.
        			 */
                    $this->_auth->getStorage()->write($adapter->getResultRowObject());
                    
                    $this->_identity = $this->_auth->getIdentity();
                    
        			/**
        			 * Заносим в таблицу users дату последнего входа пользователя
        			 */
        			// создаем объект для работы с таблицей users
        			$usersTable = new Support444_Model_DbTable_Users();
        			// формируем данные для вставки
        			$data = array('date_last_login' => new Zend_Db_Expr('NOW()'));
        			// формируем условие where
        			$where = $usersTable->getAdapter()->quoteInto('user_id = ?', $this->_identity->user_id);
        			// обновляем данные
        			$result = $usersTable->update($data, $where);
        			
        			// если не получилось вставить данные, то записываем ошибку в лог файл
        			if (!$result) {
        				$this->_logError('Произошла ошибка при попытке записи в столбец date_last_login');
        			}
                    
        			// TODO
        			if (null === $this->_requestUri) {
        			    // перенаправляем авторизованного пользователя на соответствующий раздел системы
                        switch ($this->_identity->user_type) {
                        	case 'admin':
                        		$this->getHelper('redirector')->gotoSimpleAndExit('index', 'index', 'admin');
                        	break;
                        	
                        	case 'moderator':
                        		$this->getHelper('redirector')->gotoSimpleAndExit('index', 'moderator', 'default');
                        	break;
                        	
                        	case 'user':
                        		$this->getHelper('redirector')->gotoSimpleAndExit('index', 'user', 'default');
                        	break;
                        	
                        	case 'guest':
                        		$this->getHelper('redirector')->gotoSimpleAndExit('index', 'index', 'default');
                        	break;
                        }
        			} else {
                        // Используем помощник вида для получения адреса сервера
                        // (пример результата: http://localhost)
        			    $serverUrl = $this->view->serverUrl(); 
        			    $this->getHelper('redirector')->gotoUrlAndExit($serverUrl . $this->_requestUri);
        			}
        		} else {
        		    //$this->_form->setErrors(array('auth' => 'loginFaild'));
        		    
        		    // заносим ошибку в сессию
        		    $this->_session->authError = 'loginFaild';
        		    // устанавливаем период жизни сессии в один проход
        		    $this->_session->setExpirationHops(1);
        		    
        		    // отображаем форму с сообщением об ошибке
	    			$this->view->form = $this->_form;
        			
        			// Иначе, если проверка не пройдена 
        		    // Записываем событие в лог файл
        		    $this->_logError($result);
        		    // повторно перенаправляем на стр. логина
        		    //$this->getHelper('redirector')->gotoSimpleAndExit('index', 'login', 'support444');
        		}
	    	} else {
	    		// отображаем форму с ошибками валидации
	    		$this->view->form = $this->_form;
	    	}
	    }
    }
    
	/**
     * записывает лог ощибки в файл
     * 
     * @param object $arg - объект из кторошо берем сообщение об ошибке
     * 
     * return void
     */
	private function _logError($arg)
	{
       $error = 'error: ';
        
       if ($arg instanceof Zend_Filter_Input) {
            foreach ($arg->getErrors() as $value) {
                $error .= ' ' . $value[0];
            }
        } else if (is_array($arg)) {
            foreach ($arg->getMessages() as $value) {
                $error .= ' ' . $value;
            }
        } else if (is_string($arg)) {
        	$error .= $arg;
        }
        // формируем текст сообщения об ошибке
        $msg = 'Login faild: ' . PHP_EOL
        	. '    ip: ' . $_SERVER['REMOTE_ADDR'] . PHP_EOL
            . '    comp: ' . gethostbyaddr($_SERVER['REMOTE_ADDR']) . PHP_EOL
            . '    login: ' . $this->getRequest()->getPost('login') . PHP_EOL
            . '    ' . $error . PHP_EOL
            . '---------------------------------------------------------------------' . PHP_EOL;
        // записываем лог в файл loginerrors.log
        System_Logger::log($msg, 'err', 'file', null, 'loginerrors.log');
	}
}


